{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "8ovgVMJ2Aaql"
   },
   "source": [
    "# Chapter 4 - Collections：集合物件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "LsU4q5p3BmZP"
   },
   "source": [
    "## Lists：串列"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "uR7r0OFED3L6"
   },
   "source": [
    "串列 (Lists) 是種序列 (Sequence) 物件，用中括號 (`[]`, Square brackets) 收集許多物件，並在物件之間以逗號 (`,`) 分隔。\n",
    "\n",
    "串列裡並不限於裝載相同資料型態的物件。\n",
    "\n",
    "Reference:\n",
    "\n",
    "* [List - Python Documentation](https://docs.python.org/3/library/stdtypes.html#lists)\n",
    "\n",
    "> 備註：可能有讀者在其他的程式語言中學過陣列 (Array) 的概念與用法，雖然類似，但 Python 的串列與其他程式語言的陣列畢竟本質上仍稍有不同，不能混為一談。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "poRkpZY-1MDM"
   },
   "source": [
    "### 串列的基本用法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 1095,
     "status": "ok",
     "timestamp": 1607481696653,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "lv3xyQX2FV4P",
    "outputId": "be947e70-21d5-4ec0-fd95-e6887d5c98c6"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[]\n"
     ]
    }
   ],
   "source": [
    "# 創建一個空的串列\n",
    "empty = []\n",
    "print(empty)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "bMfVwRpejWG1"
   },
   "source": [
    "> 備註：或許有些讀者會有從其他程式語言帶來的習慣，也可能曾經看過用 `list()` 建立一個新的、空的串列的用法，在此我表示不建議。在 Python 的設計中，用中括號 `[]` 就是建立一個全新的串列的標準方法，透過 `list()` constructor 的操作的意義並不一樣，連帶的會影響效率。詳情可以查看 `help(list)`。\n",
    ">\n",
    "> 所以，除非有將物件轉換為串列的用途，其餘建立串列的用途，建議都用中括號 `[]` 的寫法代替就好。而且，寫 Python 就是要寫得優雅、簡潔，何苦又將它複雜化呢？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "id": "x2iBjU12Fabd"
   },
   "outputs": [],
   "source": [
    "letters = [\"a\", \"b\", \"c\"]     # 放入字串\n",
    "numbers = [6, 5, 4, 3, 2, 1]  # 放入數字"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "id": "Ir6l-4KcJCMC"
   },
   "outputs": [],
   "source": [
    "mixed = [\"one\", 2, \"3\", [4, 5, \"F\"]]  # 混合不同資料型態物件的串列"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "yVxibQhZYrA2"
   },
   "source": [
    "在先前的內容中，我們理解字串物件是由很多的單一字元所組成，其實與串列的概念是相仿的。所以在字串中用來索引的方法，在串列也同樣適用："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 895,
     "status": "ok",
     "timestamp": 1606959812860,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "sZW8MuK-JRY2",
    "outputId": "7b29a33a-7077-4beb-be7f-cd518bf0784d"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "b\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "# 索引\n",
    "print(letters[1])  # 在充滿字串的串列中索引\n",
    "print(numbers[4])  # 在充滿數字的串列中索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 924,
     "status": "ok",
     "timestamp": 1606890755318,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "bJ1BXwJPJgxr",
    "outputId": "6395d8f3-2335-42db-ada2-25b0750b7722"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "5\n"
     ]
    }
   ],
   "source": [
    "print(mixed[2])     # 在混合不同資料型態物件的串列中索引\n",
    "print(mixed[3][1])  # 索引串列中的串列物件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 897,
     "status": "ok",
     "timestamp": 1606890837167,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "j1mTGYmgJxEM",
    "outputId": "979c79f9-e5f7-45f9-9554-1230ca774a10"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2, [4, 5, 'F']]\n"
     ]
    }
   ],
   "source": [
    "print(mixed[1::2])  # 索引的格式一樣是 list[start:stop:step]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "pH6eR4zoZhsq"
   },
   "source": [
    "字串中的字元是無法單獨被置換的，但串列可以，只要直接用等號 `=` 將新的物件指定到特定的索引值位置即可："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 1072,
     "status": "ok",
     "timestamp": 1607482190583,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "J96BD2l2RN9R",
    "outputId": "41815a1c-ce15-474a-c698-2afb6eff8e45"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['a', 'B', 'c']\n"
     ]
    }
   ],
   "source": [
    "letters[1] = \"B\"  # 置換串列內的物件\n",
    "print(letters)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "i_8lAn81bA6r"
   },
   "source": [
    "與字串當的還有可以使用 `in`: 包含測試運算子，可以驗證某物件是否包含在串列內"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 980,
     "status": "ok",
     "timestamp": 1607482563028,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "ApMrrgQ4JKxE",
    "outputId": "0fbe1356-8e72-4539-fab5-d63dbef70185"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "print(\"3\" in mixed)  # 驗證字串是否存在於串列內\n",
    "print(3 in mixed)    # 驗證數字是否存在於串列內"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 1440,
     "status": "ok",
     "timestamp": 1607482670029,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "yGT3gaPfJPMX",
    "outputId": "dbaccd47-1758-4d5e-8cfd-e1a67d1787dd"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "print(\"F\" in mixed)  # \"F\" 實際是包含在 mixed 串列中、index = 3 的串列內\n",
    "                     # 那麼驗證的結果是如何呢？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['one', 'two', '3', [4, 5, 'F']]\n"
     ]
    }
   ],
   "source": [
    "# 修改內容\n",
    "mixed[1] = \"two\"\n",
    "print(mixed)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "3dVzkL1DXryd"
   },
   "source": [
    "### 搭配內建函式使用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Nm1rRdNXYqsO"
   },
   "source": [
    "#### `len()`：計算串列內有多少物件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "bjvC5zHJm_ho"
   },
   "source": [
    "References:\n",
    "\n",
    "* [len() - Python Documentation](https://docs.python.org/3/library/functions.html#len)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 1194,
     "status": "ok",
     "timestamp": 1607482949595,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "MNnmalUJVWlu",
    "outputId": "f13dfb14-aa62-44e1-e725-5b1ad86f8657"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6\n"
     ]
    }
   ],
   "source": [
    "numbers = [6, 5, 4, 3, 2, 1]\n",
    "print(len(numbers))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 1028,
     "status": "ok",
     "timestamp": 1607483095297,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "1HCKhE3Mc_JA",
    "outputId": "a9aa2605-d6c7-4e06-a7cc-097e9801d276"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n"
     ]
    }
   ],
   "source": [
    "mixed = [\"one\", 2, \"3\", [4, 5, \"F\"]]  # 思考一下：如果串列中還有串列，這樣到底有幾個物件呢？\n",
    "print(len(mixed))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "6LG7bAJhYvkI"
   },
   "source": [
    "#### `sorted()`：對串列內的內容排序"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Pp_WB9rFepI7"
   },
   "source": [
    "要注意的是：`sorted()` 函式僅會回傳排序後的結果，串列本身並不會被修改：\n",
    "\n",
    "References:\n",
    "\n",
    "* [sorted() - Python Documentation](https://docs.python.org/3/library/functions.html#sorted)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 899,
     "status": "ok",
     "timestamp": 1607483555730,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "FiAjo-upXwS_",
    "outputId": "88546f2c-baa9-496c-dba7-d36c7b4ca0e9"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5, 6]\n",
      "[6, 5, 4, 3, 2, 1]\n"
     ]
    }
   ],
   "source": [
    "numbers = [6, 5, 4, 3, 2, 1]\n",
    "print(sorted(numbers))  # 觀察經過 sorted() 函式處理後的內容\n",
    "print(numbers)          # 觀察 numbers 串列本身：並不會被更動"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "xVQuT1yjfbHI"
   },
   "source": [
    "`sorted()`\b 預設是使用遞增排序，也可以使用遞減排序，方法是加上設定 `reverse` 參數 (Parameter) 為 `True`："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 867,
     "status": "ok",
     "timestamp": 1607483747872,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "sk-LsWNdfW3J",
    "outputId": "1da65f67-e993-49de-b873-078fab31c9bb"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[6, 5, 4, 3, 2, 1]\n"
     ]
    }
   ],
   "source": [
    "numbers = [1, 2, 3, 4, 5, 6]\n",
    "print(sorted(numbers, reverse=True))  # 遞減排序"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "vvhwtSv1f4Zt"
   },
   "source": [
    "> 備註：參數 (Parameters) 是什麼？我們將會在自訂函式的章節中提及。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "WvfnQwPlgIFM"
   },
   "source": [
    "> 順帶一提：如果要永久將串列的內容變更為排序後的結果，我們可以調用串列本身的 `list.sort()` 方法，這會在底下：串列方法的小節中介紹。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "j20qLOGhKUoN"
   },
   "source": [
    "#### `del()`：移除串列中的物件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ZMh_tzAKpyrs"
   },
   "source": [
    "References:\n",
    "\n",
    "* [The del statement - Python Documentation](https://docs.python.org/3/reference/simple_stmts.html#grammar-token-del-stmt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 835,
     "status": "ok",
     "timestamp": 1607484151234,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "NXLLdCkOKFDh",
    "outputId": "6afdf8b3-52be-402a-a47a-e38637b9eaf3"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['a', 'c', 'd', 'e', 'f', 'g']\n"
     ]
    }
   ],
   "source": [
    "letters = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"]\n",
    "del(letters[1])  # 直接在 del() 函式指定串列物件的索引值，即可移除該物件\n",
    "print(letters)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 817,
     "status": "ok",
     "timestamp": 1607485028865,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "ZchiDz8KKfq3",
    "outputId": "2763ef0c-1e1d-4d7d-ec4c-09d4b4a75f63"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['a', 'b', 'c', 'g']\n"
     ]
    }
   ],
   "source": [
    "letters = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"]\n",
    "del(letters[3:6])  # 也可以一次刪除多個物件\n",
    "print(letters)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "AHPpHpvtpoAt"
   },
   "source": [
    "> 備註：眼尖的各位可能有機會發現，其實 `del` 關鍵字在 Python 的官方文件裡是個陳述式 (statements)，其實在執行時不用寫成函式 `del()` 的型態也可以執行。\n",
    ">\n",
    "> 有什麼差異呢？執行上的感覺是沒有差異的，但礙於篇幅，暫時不多作解釋。有興趣的各位可以自行搜尋看看！"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 870,
     "status": "ok",
     "timestamp": 1607486513954,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "Y_1506N0n2UY",
    "outputId": "1fec483d-36a7-49ad-d265-2536fdb7ab1c"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['b', 'c', 'd', 'e', 'f', 'g']"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "letters = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"]\n",
    "del letters[0]  # 用陳述式的方式來操作刪除功能\n",
    "letters"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "84hRx96cLAgy"
   },
   "source": [
    "### 串列方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "2As2qjN4LD2R"
   },
   "source": [
    "#### `list.append()`：新增物件至串列內"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "sQ5i-ifkk_X9"
   },
   "source": [
    "使用 `list.append()` 方法將**一個**物件加入至現有串列內："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 976,
     "status": "ok",
     "timestamp": 1606891454191,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "qFsMrXktKr-i",
    "outputId": "6f30803a-4bfe-4ea5-a81c-c1cba59cc1a3"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']\n"
     ]
    }
   ],
   "source": [
    "letters = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"]\n",
    "letters.append(\"h\")\n",
    "print(letters)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "SLVcM-yblyOX"
   },
   "source": [
    "但 `list.append()` 方法無法一次新增多個物件："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 870,
     "status": "ok",
     "timestamp": 1606891526868,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "6jQ5XBAkK3Jk",
    "outputId": "72f5325d-a385-4cc4-8915-8494970b0c43"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['a', 'b', 'c', 'd', 'e', 'f', 'g', ['h', 'i']]\n"
     ]
    }
   ],
   "source": [
    "letters = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"]\n",
    "\n",
    "# letters.append(\"h\", \"i\")  # 無法一次新增多個物件，執行此段會出現錯誤\n",
    "\n",
    "letters.append([\"h\", \"i\"])  # 雖然可以將另一個串列加入\n",
    "                            # 但這個串列依然是以「一個物件」的身份被加入到串列內的\n",
    "print(letters)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "TVl5VV7Hl4gQ"
   },
   "source": [
    "若要將另一個串列的物件**一個個**的加入現有串列中，有兩個方法：\n",
    "\n",
    "1. 透過 `list.extend()` 方法\n",
    "2. 透過 `+` 運算子來連接兩個串列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 884,
     "status": "ok",
     "timestamp": 1607485413305,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "gGZRBDmHMtb0",
    "outputId": "7dcfdbb8-e6f3-44e1-f0b1-0bcf4be596c6"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\n"
     ]
    }
   ],
   "source": [
    "# 透過 list.extend() 方法\n",
    "letters = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"]\n",
    "letters.extend([\"h\", \"i\"])\n",
    "print(letters)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 694,
     "status": "ok",
     "timestamp": 1606892446590,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "iHOHHJJbNA9P",
    "outputId": "ad389fb4-df13-4e72-b82f-4612f7f82999"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']\n"
     ]
    }
   ],
   "source": [
    "# 透過 + 運算子來連接兩個串列\n",
    "letters = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"]\n",
    "more_letters = letters + [\"h\", \"i\", \"j\"]\n",
    "print(more_letters)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "uvOxgYHDQLoC"
   },
   "source": [
    "#### `list.remove()`：移除串列內的物件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Px5GOqXB4Zog"
   },
   "source": [
    "透過 `list.remove()` 的方式，並直接指定要刪除的物件內容。不同於使用 `del()` 或 `del` 陳述式需要指定索引值去刪除。\n",
    "\n",
    "但若有多個相符的物件，只會將**第一個**相符的物件移除："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 966,
     "status": "ok",
     "timestamp": 1607490405053,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "JAfDsyA2U-BJ",
    "outputId": "66bbea57-e8f1-475f-8f4c-6abe7bb86980"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 4, 5, 6, 7, 8, 9, 10]\n",
      "9\n"
     ]
    }
   ],
   "source": [
    "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n",
    "numbers.remove(3)  # 移除串列內的數字物件 3\n",
    "print(numbers)\n",
    "print(len(numbers))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 811,
     "status": "ok",
     "timestamp": 1607490460674,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "4bi2MYGI5TNq",
    "outputId": "663bc40d-5fb1-4ae4-8838-3a744d9960c2"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "numbers = [1, 1, 2, 3, 4, 5]\n",
    "numbers.remove(1)  # 移除串列內的數字物件 1，但因有多個相符的物件，只會刪除第一個\n",
    "print(numbers)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 1083,
     "status": "ok",
     "timestamp": 1607490527131,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "Ephn25b55eCq",
    "outputId": "644b2502-fca8-4ed0-a26c-54f0656f5a43"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1, 2, 3], 6]\n"
     ]
    }
   ],
   "source": [
    "mixed_numbers = [[1, 2, 3], [4, 5], 6]\n",
    "mixed_numbers.remove([4, 5])  # 也可以移除串列裡的串列，只要物件相符都沒有問題\n",
    "print(mixed_numbers)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Ckr2uB027vsE"
   },
   "source": [
    "#### `list.pop()`：依照後進先出規則移除物件並回傳結果"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "L_rfb2MC5vR1"
   },
   "source": [
    "而另一個移除物件的方法是呼叫 `list.pop()`。\n",
    "\n",
    "若在執行時不代入需要移除的物件，預設會以「後進先出」的方式，將索引值最大的物件給移除，並在執行的時候回傳該物件。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 992,
     "status": "ok",
     "timestamp": 1606894298675,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "gQOJsz-wVIjI",
    "outputId": "df7c7429-6b16-48d2-b178-5a23f98c14c4"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
      "10\n",
      "9\n"
     ]
    }
   ],
   "source": [
    "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n",
    "dropped_number = numbers.pop()  # 不代入需要移除的物件，則物件將會移除並回傳\n",
    "                                # 所以我們可以將回傳的內容存放於一個物件中\n",
    "print(numbers)\n",
    "print(dropped_number)\n",
    "print(len(numbers))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "-u6m2FSw8Ef2"
   },
   "source": [
    "也可以代入欲移除的索引值，一樣會移除並回傳物件內容："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 989,
     "status": "ok",
     "timestamp": 1607491181445,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "AuHgyXTi763y",
    "outputId": "f4a24ec4-3144-44cb-d7cd-40902fcae8c0"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5, 6, 7, 9, 10]\n",
      "8\n",
      "9\n"
     ]
    }
   ],
   "source": [
    "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n",
    "dropped_number = numbers.pop(7)  # 指定要移除的物件索引值\n",
    "print(numbers)\n",
    "print(dropped_number)\n",
    "print(len(numbers))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "42wNFOCg6mYe"
   },
   "source": [
    "#### `list.sort()`：排序串列內的物件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "F_M69Q576pFO"
   },
   "source": [
    "與使用 `sorted()` 函式不同的地方是：調用 `list.sort()` 方法將永久改變串列的內容，且執行的當下不會回傳任何結果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 741,
     "status": "ok",
     "timestamp": 1606901539539,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "qvxOzfvVWvRd",
    "outputId": "9fb4fc6b-588e-4144-9a12-e1b5ec50a970"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[6, 5, 4, 3, 2, 1]\n",
      "[1, 2, 3, 4, 5, 6]\n"
     ]
    }
   ],
   "source": [
    "numbers = [6, 5, 4, 3, 2, 1]\n",
    "print(numbers)\n",
    "\n",
    "# 使用 list.sort() 方法排序\n",
    "numbers.sort()  # 串列的 list.sort() 方法並不會回傳結果，所以可以單獨執行\n",
    "print(numbers)  # 串列內容已被變更為排序後的結果"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "wsfCU8d7zVd6"
   },
   "source": [
    "## Dicts: Dictionaries 字典"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "fDnqmxwzzqxM"
   },
   "source": [
    "就如其名「字典」一樣的形式，`dict` 物件需要由 Key（鍵）去對應到相對的 Value（值），所以有時候會稱這種物件為 Mapping type：對應的資料型態，或稱為 Key : Value pair：鍵值對（每一筆資料都是由成對的鍵與值組成）。\n",
    "\n",
    "字典的建立是用大括號 `{}` (Curly brackets) 將一個一個鍵值對以冒號 `:` 隔開後，置於大括號之內。每一個鍵必須是獨一無二的內容，不可重複。\n",
    "\n",
    "Reference:\n",
    "\n",
    "* [Dict - Python Documentation](https://docs.python.org/3/library/stdtypes.html#mapping-types-dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "KTKpxUYp1Plv"
   },
   "source": [
    "### 字典的基本用法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 1205,
     "status": "ok",
     "timestamp": 1607502891161,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "X86cc1yF0bpv",
    "outputId": "3b26362b-1966-4d86-c6ff-ac4421e6d48a"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{}\n"
     ]
    }
   ],
   "source": [
    "# 創建一個空的字典\n",
    "d = {}\n",
    "print(d)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "lkDCqOFho4a6"
   },
   "source": [
    "> 備註：如同前面串列提到的相似，在此還是建議：建立一個新的字典物件一律使用大括號 `{}` 建立，`dict()` constructor 還是建議在需要做型態轉換時使用。\n",
    ">\n",
    "> 保持程式的簡潔及可讀性，是 Python 開發者留給這個世界的最佳禮物！"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 938,
     "status": "ok",
     "timestamp": 1607503344056,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "LUOj438QqWRq",
    "outputId": "f2081461-6060-425d-8ded-5aa39f252b94"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'Vivi', 'age': 18}\n"
     ]
    }
   ],
   "source": [
    "# 拿個人的基本資料，做一個簡單的範例\n",
    "profile = {\n",
    "    \"name\": \"Vivi\",  # 名字\n",
    "    \"age\": 18        # 年齡\n",
    "}\n",
    "print(profile)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "4w0fhaNUKGVt"
   },
   "source": [
    "> 補充：現在起，各位應該會寫一些較複雜、多行的表達式。在 Python 中，要表示物件的階層關係，是在底下多一層時，加入用**四個空白鍵**空白組成的縮排。\n",
    "> 或許有讀者在其他語言的習慣是兩個空白鍵，或是用 <button>Tab ↹</button> 按鈕來縮排，不過不建議這樣做。詳情請參考 [PEP 8](https://www.python.org/dev/peps/pep-0008/#indentation) 及 [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html#s3.4-indentation) 文件中關於 Indentation 的章節。\n",
    ">\n",
    "> \n",
    "> 以下舉例說明："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "id": "AMOej1mYK59j"
   },
   "outputs": [],
   "source": [
    "obj = {\n",
    "    \"Level-1\": {\n",
    "        \"Level-2\": {\n",
    "            \"Level-3\": {\n",
    "                # ......依此類推\n",
    "            }\n",
    "        }\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "0VPkJcLMrzNA"
   },
   "source": [
    "> 備註：因為字典物件的內容通常比較複雜，為了讓各位比較好閱讀，這裡用個內建的模組 `pprint` 來輔助顯示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "id": "pt4o_AQRrl5f"
   },
   "outputs": [],
   "source": [
    "from pprint import pprint"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Q18phfnm0y1d"
   },
   "source": [
    "備註：`import` 跟 `from` 都是在載入模組 (Module) 時會用到的陳述句，在本次的課程中會比較少見，請大家先記著就好。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 856,
     "status": "ok",
     "timestamp": 1607561592028,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "IKu0tyxy0fuy",
    "outputId": "fec72715-090d-4e37-ac4a-49ccda4f1050"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'age': 18,\n",
      " 'memo': 'I wanna go home',\n",
      " 'name': 'Vivi',\n",
      " 'skills': ['eating', 'sleeping', 'doing nothing', 'being lazy']}\n"
     ]
    }
   ],
   "source": [
    "# 再做得稍微複雜一點\n",
    "profile = {\n",
    "    \"name\": \"Vivi\",\n",
    "    \"age\": 18,\n",
    "    \"skills\": [\n",
    "        \"eating\",\n",
    "        \"sleeping\",\n",
    "        \"doing nothing\",\n",
    "        \"being lazy\",\n",
    "    ],\n",
    "    \"memo\": \"I wanna go home\",\n",
    "}\n",
    "pprint(profile)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 1269,
     "status": "ok",
     "timestamp": 1607504842700,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "vbiICVCi06Gm",
    "outputId": "7a218b41-29f1-468b-9b4b-5adb6489c00e"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Vivi\n",
      "['eating', 'sleeping', 'doing nothing', 'being lazy']\n"
     ]
    }
   ],
   "source": [
    "# 索引\n",
    "print(profile[\"name\"])    # 調閱個人檔案內的名字\n",
    "print(profile[\"skills\"])  # 調閱個人檔案內的技能"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 1112,
     "status": "ok",
     "timestamp": 1607504842701,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "H6JB_irEQca6",
    "outputId": "62fa6ff3-6b91-4275-ced7-f027ef71428b"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "32\n"
     ]
    }
   ],
   "source": [
    "# 置換已經存在的內容\n",
    "profile[\"age\"] = 32\n",
    "print(profile[\"age\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 745,
     "status": "ok",
     "timestamp": 1607504844084,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "zwKhT1hbrRg7",
    "outputId": "3213009e-b5e1-46b6-fc9e-f05ec5f14683"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'age': 32,\n",
      " 'deposit': 100000,\n",
      " 'memo': 'I wanna go home',\n",
      " 'name': 'Vivi',\n",
      " 'skills': ['eating', 'sleeping', 'doing nothing', 'being lazy']}\n"
     ]
    }
   ],
   "source": [
    "# 新增內容\n",
    "profile[\"deposit\"] = 100000  # 透過指定內容到不存在的鍵上以新增內容\n",
    "pprint(profile)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 926,
     "status": "ok",
     "timestamp": 1607504845593,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "TgDHvgVu1HLi",
    "outputId": "3ac16c1d-6e74-4179-e6a2-288b3664b147"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'age': 32,\n",
      " 'deposit': 100000,\n",
      " 'name': 'Vivi',\n",
      " 'skills': ['eating', 'sleeping', 'doing nothing', 'being lazy']}\n"
     ]
    }
   ],
   "source": [
    "# 刪除內容\n",
    "del(profile[\"memo\"])  # 刪除指定的鍵\n",
    "pprint(profile)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "xdWicJcCsYeq"
   },
   "source": [
    "使用 `in`: 包含測試運算子，可以驗證某物件是否包含在字典的鍵之內："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 770,
     "status": "ok",
     "timestamp": 1607504847188,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "h-CD7d4Smo_K",
    "outputId": "3d3ae133-1a05-46eb-b110-a6d48d87f5b0"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "# 驗證 skills 是否存在於 profile 字典物件的鍵之內\n",
    "print(\"skills\" in profile)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 790,
     "status": "ok",
     "timestamp": 1607504848992,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "Lme0TiDOmyU8",
    "outputId": "3fe6fac3-d434-4bb5-94cb-d9c25b446420"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "# 測試一下：是否可以用 in 來檢查物件是否存在於該字典的值之內？不行。\n",
    "print(\"eating\" in profile)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "YOiQD2yJtDuz"
   },
   "source": [
    "> 備註：那是否可以用別的方法，來檢查某物件是否存在於字典內的任何值之內？這邊先緩緩，等到後面的章節教完以後，就會有方法了。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "fABRLrHxMCwo"
   },
   "source": [
    "### 字典方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "PULwQuu4ta5A"
   },
   "source": [
    "#### `dict.get()`：獲得字典內特定鍵的值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 1298,
     "status": "ok",
     "timestamp": 1607504852354,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "37rBnqkxME7i",
    "outputId": "5ef75383-9b1f-43f6-c4ab-d9e58b169439"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Vivi\n",
      "Vivi\n"
     ]
    }
   ],
   "source": [
    "print(profile.get(\"name\"))\n",
    "print(profile[\"name\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "mUXOHdKGtjNH"
   },
   "source": [
    "在上面的範例中，`profile.get(\"name\"))` 與 `print(profile[\"name\"]` 的表達式是等價的。那差別在哪裡呢？在於今天如果無法確定某鍵是否存在於字典內，用 `dict.get()` 方法可以在遇到鍵不存在的情況值回傳 `None` 物件，而用索引的方式則會直接出現錯誤。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 863,
     "status": "ok",
     "timestamp": 1607504853409,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "vRE6hhDlMV3n",
    "outputId": "94cf4265-d521-4491-9a20-15491d677925"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    }
   ],
   "source": [
    "# 測試從不存在的鍵之內獲得值\n",
    "print(profile.get(\"salary\"))\n",
    "# print(profile[\"salary\"])  # 用索引的方式獲值，在該鍵不存在時會引發 Runime error"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Z-g0SWgIukRT"
   },
   "source": [
    "#### `dict.keys()`：獲得字典內的所有鍵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 634,
     "status": "ok",
     "timestamp": 1607504855046,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "_OwHuKOZMy_I",
    "outputId": "f2fe16e4-8553-4c26-e908-b9a089f88ba5"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['name', 'age', 'skills', 'deposit'])\n"
     ]
    }
   ],
   "source": [
    "print(profile.keys())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "KsayxE-uuusU"
   },
   "source": [
    "#### `dict.pop()`：移除字典內的物件並回傳結果"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "CEKPAa6wv2fL"
   },
   "source": [
    "與串列的用法相似，調用 `dict.pop()` 並代入欲從字典內移除的鍵，將可以將該鍵值對移除、並回傳該鍵的值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 854,
     "status": "ok",
     "timestamp": 1607504861185,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "iB6rISaTM_qE",
    "outputId": "20832265-9429-4870-f0ca-6c0a9cd11e63"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "32\n",
      "{'deposit': 100000,\n",
      " 'name': 'Vivi',\n",
      " 'skills': ['eating', 'sleeping', 'doing nothing', 'being lazy']}\n"
     ]
    }
   ],
   "source": [
    "# 將個人資料中的年齡移除，並存放於物件中\n",
    "vivi_age = profile.pop(\"age\")\n",
    "print(vivi_age)\n",
    "pprint(profile)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "dOvosknSyqUh"
   },
   "source": [
    "## 複製可變型別物件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "CZ43RPOVxL7V"
   },
   "source": [
    "在 Python 物件中，其實有著**可變** (Mutable) 型態與**不可變** (Immutable) 型態的區別。到目前為止，在我們學到的物件中：\n",
    "\n",
    "* 不可變 (Immutable) 型態：`int`, `float`, `str`\n",
    "* 可變型態 (Mutable) 型態：`list`, `dict`\n",
    "\n",
    "而對於可變型態的物件，在想要複製此物件時，如果沒有透過呼叫該物件的 `copy()` 方法，存粹用等號 `=` 將可變型態物件指定到一個新的物件上，將導致兩個物件實際上依然指向同一個記憶體位置，而編輯一個物件時，另一個物件依然會被更動到。\n",
    "\n",
    "以下我們分別針對串列及字典來處理這個問題。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "1erP_jCrOaEz"
   },
   "source": [
    "### 複製串列"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "35Rg6DxuzRln"
   },
   "source": [
    "我們先測試用等號 `=` 將串列指定給一個新的物件，並嘗試對任意一個串列操作："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 834,
     "status": "ok",
     "timestamp": 1607505690436,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "fTwvoFHgNODA",
    "outputId": "9ea44434-19d2-4292-81be-7499946a1cd5"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5]\n",
      "[1, 2, 3, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "list_1 = [1, 2, 3, 4, 5]  # 建立新串列物件\n",
    "list_2 = list_1           # 將原串列指定給新的物件\n",
    "print(list_1)\n",
    "print(list_2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 714,
     "status": "ok",
     "timestamp": 1606959177597,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "RKc4qjnMOrWu",
    "outputId": "00b24c33-8909-405b-9ad4-e980774dbd30"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4]\n",
      "[1, 2, 3, 4]\n"
     ]
    }
   ],
   "source": [
    "list_1.pop()  # 移除串列中的物件\n",
    "print(list_1)\n",
    "print(list_2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "EIXrBlbqzu1s"
   },
   "source": [
    "原本我們只執行 `list_1` 串列的 `pop()` 方法，移除了 `list_1` 串列中的最後一個物件，實際發生的情況是：`list_2` 串列中的物件也一併被移除了。\n",
    "\n",
    "所以我們可以調用 `list.copy()` 方法來複製串列物件："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 923,
     "status": "ok",
     "timestamp": 1607505866203,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "ytMJ4D8FOyoZ",
    "outputId": "39674aff-037e-403b-98cb-5a9476c8445f"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5]\n",
      "[1, 2, 3, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "list_1 = [1, 2, 3, 4, 5]  # 建立新串列物件\n",
    "list_2 = list_1.copy()    # 複製串列為新的物件\n",
    "print(list_1)\n",
    "print(list_2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 1056,
     "status": "ok",
     "timestamp": 1607505901180,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "tchQ7w7sO47r",
    "outputId": "e92817d6-774b-4d73-d15c-9fc629b85e32"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4]\n",
      "[1, 3, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "list_1.pop()      # 將 list_1 串列中的最後一個物件移除\n",
    "list_2.remove(2)  # 將 list_2 串列中的 2 物件移除\n",
    "print(list_1)\n",
    "print(list_2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "eqd0SJE80XjL"
   },
   "source": [
    "由此可見，兩個物件就有成功被獨立開來了。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "8wReUBgXP5Qu"
   },
   "source": [
    "### 複製字典"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "2uQr8bKFIZrm"
   },
   "source": [
    "接著，我們一樣先測試用等號 `=` 將字典指定給另一個物件，並嘗試對任意一個字典進行操作："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 788,
     "status": "ok",
     "timestamp": 1607561671133,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "WXOdZKjeP7E-",
    "outputId": "64041d8f-e9ee-47e4-9c10-86059d231677"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'more': {'four': 4, 'three': 3}, 'one': 1, 'two': 2}\n",
      "{'more': {'four': 4, 'three': 3}, 'one': 1, 'two': 2}\n"
     ]
    }
   ],
   "source": [
    "dict_1 = {       # 建立新字典物件\n",
    "    \"one\": 1,\n",
    "    \"two\": 2,\n",
    "    \"more\": {\n",
    "        \"three\": 3,\n",
    "        \"four\": 4\n",
    "    }\n",
    "}\n",
    "dict_2 = dict_1  # 將原字典指定給新的物件\n",
    "pprint(dict_1)\n",
    "pprint(dict_2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 1338,
     "status": "ok",
     "timestamp": 1607561785245,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "zemnr57XQSzu",
    "outputId": "183fd0ac-fcdd-4355-c9ec-3431f71b7253"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'more': {'four': 4, 'three': 3}, 'one': 'The first number', 'two': 2}\n",
      "{'more': {'four': 4, 'three': 3}, 'one': 'The first number', 'two': 2}\n"
     ]
    }
   ],
   "source": [
    "dict_1[\"one\"] = \"The first number\"  # 新增一個鍵值對\n",
    "pprint(dict_1)\n",
    "pprint(dict_2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Np1lqf33Jmuh"
   },
   "source": [
    "看起來我們在 `dict_1` 新增了一個鍵，但是 `dict_2` 也一樣受到影響了。\n",
    "\n",
    "接著我們就來調用 `dict.copy()` 方法來複製字典："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 948,
     "status": "ok",
     "timestamp": 1607562899118,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "IEU-bJThSqQ3",
    "outputId": "fffd78bf-b3ef-47cf-e3a4-5a3951ea7400"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'more': {'four': 4, 'three': 3}, 'one': 1, 'two': 'The second number'}\n",
      "{'more': {'four': 4, 'three': 3}, 'one': 1, 'two': 2}\n"
     ]
    }
   ],
   "source": [
    "dict_1 = {                           # 建立新字典物件\n",
    "    \"one\": 1,\n",
    "    \"two\": 2,\n",
    "    \"more\": {\n",
    "        \"three\": 3,\n",
    "        \"four\": 4\n",
    "    }\n",
    "}\n",
    "dict_2 = dict_1.copy()               # 複製字典為新的物件\n",
    "dict_1[\"two\"] = \"The second number\"  # 新增一個鍵值對\n",
    "pprint(dict_1)\n",
    "pprint(dict_2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "BvJelLwLMc63"
   },
   "source": [
    "看似可以正確地將字典複製出來了！接著我們看一個更進階的範例：如果在字典物件裡面對裡面的字典操作呢？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 551,
     "status": "ok",
     "timestamp": 1607562900596,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "BRN2Ul2mTGhI",
    "outputId": "0b78344a-2221-46c4-deae-0ade8520c42c"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'more': {'four': 4, 'three': 'The third number'},\n",
      " 'one': 1,\n",
      " 'two': 'The second number'}\n",
      "{'more': {'four': 4, 'three': 'The third number'}, 'one': 1, 'two': 2}\n"
     ]
    }
   ],
   "source": [
    "dict_1[\"more\"][\"three\"] = \"The third number\"  # 對 dict_1[\"mode\"] 字典新增一個鍵值對\n",
    "pprint(dict_1)\n",
    "pprint(dict_2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "v8S6p5koM6B_"
   },
   "source": [
    "看起來，`dict.copy()` 方法雖然可以成功地複製出字典，但針對「字典中的字典」卻沒有辦法好好複製出來、成為一個獨立的物件。於是我們要透過內建的 `copy` 模組中的 `deepcopy` 函式來解決這個問題："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "id": "rpmDhqpKTY-p"
   },
   "outputs": [],
   "source": [
    "from copy import deepcopy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 1105,
     "status": "ok",
     "timestamp": 1607562906380,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "4Jgm9ab6TXXU",
    "outputId": "a8598cae-64e0-4e0e-f3cf-0cbb35fe49db"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'more': {'four': 4, 'three': 3}, 'one': 1, 'two': 2}\n",
      "{'more': {'four': 4, 'three': 3}, 'one': 1, 'two': 2}\n"
     ]
    }
   ],
   "source": [
    "dict_1 = {                 # 建立新字典物件\n",
    "    \"one\": 1,\n",
    "    \"two\": 2,\n",
    "    \"more\": {\n",
    "        \"three\": 3,\n",
    "        \"four\": 4\n",
    "    }\n",
    "}\n",
    "dict_2 = deepcopy(dict_1)  # 使用 deepcopy() 函式來複製字典\n",
    "pprint(dict_1)\n",
    "pprint(dict_2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 887,
     "status": "ok",
     "timestamp": 1607562914810,
     "user": {
      "displayName": "黃種平",
      "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GjCoYcYDAMAK-J-MvClxwWJY0fvKYsny6BL962ZNA=s64",
      "userId": "12486487678081777487"
     },
     "user_tz": -480
    },
    "id": "W_9KtJuCNu3K",
    "outputId": "10620176-c2e5-4dd2-c4c4-b61186fc74a6"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'more': {'four': 4, 'three': 'The third number'},\n",
      " 'one': 1,\n",
      " 'two': 'The second number'}\n",
      "{'more': {'four': 4, 'three': 3}, 'one': 1, 'two': 2}\n"
     ]
    }
   ],
   "source": [
    "dict_1[\"two\"] = \"The second number\"           # 在字典中新增鍵值對\n",
    "dict_1[\"more\"][\"three\"] = \"The third number\"  # 在字典中的字典新增鍵值對\n",
    "pprint(dict_1)\n",
    "pprint(dict_2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "NIbp6ZLYN2f1"
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "colab": {
   "authorship_tag": "ABX9TyMlQmXI5C3NIqNum3daZN1m",
   "collapsed_sections": [],
   "name": "Python Basics - Chapter 4 - Collections.ipynb",
   "provenance": [],
   "toc_visible": true
  },
  "jupytext": {
   "formats": "ipynb,py:light"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
